/****************************************************************
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.     *
 *                                                              *
 * Copyright (C) 2009, Jun Li All rights reserved.              *
 * More about Jun{                                              *
 * Homepage: http://www.jpxx.org/                               *
 * Email   : lijun@jpxx.org                                     *
 * }                                                            *
 * SOFTWARE ENGINEERING COLLEGE OF SICHUAN UNIVERSITY           *
 *                                                              *
 ****************************************************************/
package org.jpxx.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Compresses files to ZIP format.
 * 
 * @author Jun Li lijun@jpxx.org (http://www.jpxx.org)
 * @version 1.0.0 $ org.jpxx.util.ZipBuilder.java $ $ Date: 2009-5-16 $
 */
public class ZipBuilder {
	protected ZipOutputStream zip = null;
	protected byte[] syncBuffer = null;

	public ZipBuilder(String zipFileName) {

		try {
			syncBuffer = new byte[8192];
			FileUtils.mkParentDirs(zipFileName);
			FileOutputStream out = new FileOutputStream(zipFileName);
			zip = new ZipOutputStream(out);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * synchronized for using syncBuffer
	 * 
	 * @param f
	 *            file to add
	 * @param relName
	 *            relative name inside jar
	 */
	protected synchronized void add(File f, String relName) {

		try {
			if (f.isDirectory()) {
				String dirName = relName.replace(File.separatorChar, '/');
				if (!dirName.endsWith("/"))
					dirName += "/";
				ZipEntry entry = new ZipEntry(dirName);
				zip.putNextEntry(entry);
				zip.closeEntry();
			} else {
				ZipEntry entry = new ZipEntry(relName.replace(
						File.separatorChar, '/'));
				entry.setSize(f.length());
				entry.setTime(f.lastModified());
				zip.putNextEntry(entry);
				FileInputStream in = new FileInputStream(f);
				int cnt = in.read(syncBuffer);
				while (cnt > 0) {
					zip.write(syncBuffer, 0, cnt);
					cnt = in.read(syncBuffer);
				}
				zip.closeEntry();
				in.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	protected void close() {

		try {
			zip.flush();
			zip.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将制定目录的文件打包。UNIX系统定义的隐藏文件将被过滤。
	 * 
	 * @param path
	 *            带打包的文件夹路径
	 */
	public void build(String path) {

		path = path.replace('\\', '/');

		List<String> list = FileUtils.listAllFiles(path);
		for (int i = 0; i < list.size(); i++) {
			String filePath = list.get(i);
			String temp = filePath;
			temp = temp.replace(path, "");
			add(new File(filePath), temp);

		}
		close();
	}

}
